#include "HttpServer.hpp"
#include "Session.hpp"

using namespace LogModule;


std::string GetMonthName(int month)
{
    std::vector<std::string> months = {"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"};
    return months[month];
}
std::string GetWeekDayName(int day)
{
    std::vector<std::string> weekdays = {"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"};
    return weekdays[day];
}
std::string ExpireTimeRfc1123(int t) // 秒级别的未来UTC时间
{
    time_t timeout = time(nullptr) + t;
    struct tm *tm = gmtime(&timeout); // 这里不能用localtime，因为localtime是默认带了时区的. gmtime获取的就是UTC统一时间
    char timebuffer[1024];
    //时间格式如: expires=Thu, 18 Dec 2024 12:00:00 UTC
    snprintf(timebuffer, sizeof(timebuffer), "%s, %02d %s %d %02d:%02d:%02d UTC", 
        GetWeekDayName(tm->tm_wday).c_str(),
        tm->tm_mday,
        GetMonthName(tm->tm_mon).c_str(),
        tm->tm_year+1900,
        tm->tm_hour,
        tm->tm_min,
        tm->tm_sec
    );
    return timebuffer;
}



void Login(HttpRequest &req, HttpResponse &resp)
{
    // req.Path(): /login
    // 根据req，动态构建username=lisi&password=aa
    LOG(LogLevel::DEBUG) << "进入登录模块" << req.Path() << ", " << req.Args();
    std::string req_args = req.Args();

// 获得登录账号密码
    ssize_t pos = req_args.find("&");
    std::string username = req_args.substr(0, pos);
    std::string passwd = req_args.substr(pos + 1);


// 1. 测试 cookie 被写入和自动提交 
    // resp.SetHeader("Set-Cookie", "usename=zs;");
    // resp.SetHeader("Set-Cookie", "passwd=123;");
    // resp.SetHeader("Set-Cookie", "usename=zs&passwd=123;");

// 2. 测试过期时间写入
    // resp.SetHeader("Set-Cookie: username=zs ", "expires= " + ExpireTimeRfc1123(15) + ";");

// 3. Session 测试
    session_ptr s = std::make_shared<Session>(username, true);
    std::string sessionid = _session_manager.AddSession(s);
    LOG(LogLevel::DEBUG) << username << " 被添加, sessionid是: " << sessionid;
    resp.SetHeader("Set-Cookie", "sessionid=" + sessionid + "; expires=" + ExpireTimeRfc1123(60000) + ";  path=/;"); // 让 cookie 1min 过期



    // 1. 解析参数格式, 得到想要参数

    // 2. 访问数据库, 验证对应的用户是否合法的用户, 其他工作.../
    // SessionManager m;
    // session id = m.CreateSession("XXX"); 

    // 3. 登录成功
    // std::string body = "<html><body><p>Login Success!</p></body></html>"; // test
    std::string body = req.GetContent("wwwroot/success.html");
    resp.SetCode(200);
    resp.SetHeader("Content-Length", std::to_string(body.size()));
    resp.SetHeader("Content-Type", "text/html");


    resp.SetBody(body);

    // 4. 重定向
    // resp.SetCode(302);
    // resp.SetHeader("Location", "/"); // 设置回到首页

}
void Register(HttpRequest &req, HttpResponse &resp)
{
    // 根据req，动态构建resp
    LOG(LogLevel::DEBUG) << "进入注册模块" << req.Path() << ", " << req.Args();
}

void Search(HttpRequest &req, HttpResponse &resp)
{
    // 根据req，动态构建resp
    LOG(LogLevel::DEBUG) << "进入搜索模块" << req.Path() << ", " << req.Args();
}

void Test(HttpRequest &req, HttpResponse &resp)
{
    // 根据req，动态构建resp
    LOG(LogLevel::DEBUG) << "进入测试模块" << req.Path() << ", " << req.Args();
}


int main(int argc, char *argv[])
{
    if(argc != 2)
    {
        std::cout << "Usage: " << argv[0] << " port" << std::endl;
        return 1;
    }
    auto httpserver = std::make_unique<HttpServer>(std::stoi(argv[1]));
     // 要让服务器具有登录功能
    httpserver->Resgiter("/login", Login);
    httpserver->Resgiter("/register", Register);
    httpserver->Resgiter("/search", Search);
    httpserver->Resgiter("/test", Test);
    
    httpserver->Start();
    return 0;
}